1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.testers;
18  
19  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
20  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
21  import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
22  
23  import com.google.common.annotations.GwtCompatible;
24  import com.google.common.annotations.GwtIncompatible;
25  import com.google.common.collect.testing.Helpers;
26  import com.google.common.collect.testing.features.CollectionFeature;
27  import com.google.common.collect.testing.features.CollectionSize;
28  import com.google.common.collect.testing.features.ListFeature;
29  
30  import java.lang.reflect.Method;
31  
32  /**
33   * A generic JUnit test which tests {@code set()} operations on a list. Can't be
34   * invoked directly; please see
35   * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
36   *
37   * @author George van den Driessche
38   */
39  @GwtCompatible(emulated = true)
40  public class ListSetTester<E> extends AbstractListTester<E> {
41    @ListFeature.Require(SUPPORTS_SET)
42    @CollectionSize.Require(absent = ZERO)
43    public void testSet() {
44      doTestSet(samples.e3);
45    }
46  
47    @CollectionSize.Require(absent = ZERO)
48    @CollectionFeature.Require(ALLOWS_NULL_VALUES)
49    @ListFeature.Require(SUPPORTS_SET)
50    public void testSet_null() {
51      doTestSet(null);
52    }
53  
54    @CollectionSize.Require(absent = ZERO)
55    @CollectionFeature.Require(ALLOWS_NULL_VALUES)
56    @ListFeature.Require(SUPPORTS_SET)
57    public void testSet_replacingNull() {
58      E[] elements = createSamplesArray();
59      int i = aValidIndex();
60      elements[i] = null;
61      collection = getSubjectGenerator().create(elements);
62  
63      doTestSet(samples.e3);
64    }
65  
66    private void doTestSet(E newValue) {
67      int index = aValidIndex();
68      E initialValue = getList().get(index);
69      assertEquals("set(i, x) should return the old element at position i.",
70          initialValue, getList().set(index, newValue));
71      assertEquals("After set(i, x), get(i) should return x",
72          newValue, getList().get(index));
73      assertEquals("set() should not change the size of a list.",
74          getNumElements(), getList().size());
75    }
76  
77    @ListFeature.Require(SUPPORTS_SET)
78    public void testSet_indexTooLow() {
79      try {
80        getList().set(-1, samples.e3);
81        fail("set(-1) should throw IndexOutOfBoundsException");
82      } catch (IndexOutOfBoundsException expected) {
83      }
84      expectUnchanged();
85    }
86  
87    @ListFeature.Require(SUPPORTS_SET)
88    public void testSet_indexTooHigh() {
89      int index = getNumElements();
90      try {
91        getList().set(index, samples.e3);
92        fail("set(size) should throw IndexOutOfBoundsException");
93      } catch (IndexOutOfBoundsException expected) {
94      }
95      expectUnchanged();
96    }
97  
98    @CollectionSize.Require(absent = ZERO)
99    @ListFeature.Require(absent = SUPPORTS_SET)
100   public void testSet_unsupported() {
101     try {
102       getList().set(aValidIndex(), samples.e3);
103       fail("set() should throw UnsupportedOperationException");
104     } catch (UnsupportedOperationException expected) {
105     }
106     expectUnchanged();
107   }
108 
109   @CollectionSize.Require(ZERO)
110   @ListFeature.Require(absent = SUPPORTS_SET)
111   public void testSet_unsupportedByEmptyList() {
112     try {
113       getList().set(0, samples.e3);
114       fail("set() should throw UnsupportedOperationException "
115           + "or IndexOutOfBoundsException");
116     } catch (UnsupportedOperationException tolerated) {
117     } catch (IndexOutOfBoundsException tolerated) {
118     }
119     expectUnchanged();
120   }
121 
122   @CollectionSize.Require(absent = ZERO)
123   @ListFeature.Require(SUPPORTS_SET)
124   @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
125   public void testSet_nullUnsupported() {
126     try {
127       getList().set(aValidIndex(), null);
128       fail("set(null) should throw NullPointerException");
129     } catch (NullPointerException expected) {
130     }
131     expectUnchanged();
132   }
133 
134   private int aValidIndex() {
135     return getList().size() / 2;
136   }
137 
138   /**
139    * Returns the {@link java.lang.reflect.Method} instance for
140    * {@link #testSet_null()} so that tests of {@link
141    * java.util.Collections#checkedCollection(java.util.Collection, Class)} can
142    * suppress it with {@code FeatureSpecificTestSuiteBuilder.suppressing()}
143    * until <a
144    * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6409434">Sun bug
145    * 6409434</a> is fixed. It's unclear whether nulls were to be permitted or
146    * forbidden, but presumably the eventual fix will be to permit them, as it
147    * seems more likely that code would depend on that behavior than on the
148    * other. Thus, we say the bug is in set(), which fails to support null.
149    */
150   @GwtIncompatible("reflection")
151   public static Method getSetNullSupportedMethod() {
152     return Helpers.getMethod(ListSetTester.class, "testSet_null");
153   }
154 }